home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-05-29 | 25.6 KB | 844 lines | [TEXT/CWIE] |
- unit NSSprites;
-
- interface
-
- uses
- Types, Quickdraw, QDOffscreen;
-
- {
- Required colour quickdraw
- All internal worlds are 8-bit
- }
-
- {$ifc undefined useNSBlitter}
- {$setc useNSBlitter := 1}
- {$endc}
-
- {$ifc not GENERATINGCFM}
- var
- needSwapMMUMode: boolean;
- {$endc}
-
- const
- max_sprite_size = 32;
- max_sprite_area_size = 1280;
- grid_size = max_sprite_size;
- max_grid_size = max_sprite_area_size div max_sprite_size;
-
- const
- change_rect_max = 200;
- kNoSprite = -1;
-
- type
- BlitterProc = procedure( sprite_refcon: longint; source: NSFramePtr; const source_rect, mask_rect: Rect; dest: NSFramePtr; const dest_rect: Rect );
-
- NSList = record
- next: NSListPtr;
- prev: NSListPtr;
- head: boolean;
- end;
- NSListPtr = ^NSList;
-
- NSWorld = record
- background: NSFramePtr;
- work: NSFramePtr;
- sprite: NSFramePtr;
- window: NSFramePtr;
- sprites: NSSpritePtr;
- offscreen_blitter: BlitterProc;
- change_rects: array[1..change_rect_max] of Rect;
- change_rect_count: longint;
- grid: array[-1..max_grid_size-1, -1..max_grid_size-1] of NSList;
- end;
- NSWorldPtr = ^NSWorld;
-
- NSFrame = record
- world: GWorldPtr;
- pixMap: PixMapPtr;
- frameBaseAddr: Ptr;
- rowBytes: longint;
- bounds: Rect;
- dispose_gworld: boolean;
- end;
- NSFramePtr = ^NSFrame;
-
- NSSprite = record
- grid: NSList; { WARNING: fix up sprite_to_grid_offset if this moves! }
- next: NSSpritePtr;
- world: NSWorldPtr;
- source_rect: Rect;
- mask_rect: Rect;
- dest_rect: Rect;
- blitter: BlitterProc;
- refcon: longint;
- visible: boolean;
- end;
- NSSpritePtr = ^NSSprite;
-
- NSSavedPort = record
- world: GWorldPtr;
- device: GDHandle;
- end;
-
- const
- sprite_to_grid_offset = 0;
-
- const
- kSpriteAfterNone = nil; { cheap }
- kSpriteAfterAll = NSSpritePtr(-1); { expensive }
-
- procedure NSInitSprites;
-
- function NSCreateWorld( var world: NSWorldPtr; window: WindowPtr; const window_bounds, sprite_frame: Rect ): OSStatus;
- procedure NSDestroyWorld( var world: NSWorldPtr );
- function NSResize( var world: NSWorldPtr; const newframe: Rect ): OSStatus;
- { WARNING: If NSResize fails, it destroys the NSWorld! }
-
- procedure NSGetGWorld( var saved: NSSavedPort );
- procedure NSSetGWorld( world: GWorldPtr; var saved: NSSavedPort );
- procedure NSRestoreGWorld( const saved: NSSavedPort );
-
- procedure NSAddChangeRect( world: NSWorldPtr; changeRect: Rect );
- { call this if you change the background }
-
- procedure NSAnimate( world: NSWorldPtr );
- procedure NSUpdate( world: NSWorldPtr; update: Rect );
-
- function NSCreateSprite( var sprite: NSSpritePtr; world: NSWorldPtr; const source_rect, mask_rect: Rect ): OSStatus; // after: NSSpritePtr;
- procedure NSDestroySprite( var sprite: NSSpritePtr );
-
- procedure NSSetSpriteVisible( sprite: NSSpritePtr; visible: boolean );
- procedure NSSetSpriteLocation( sprite: NSSpritePtr; h, v: integer );
- procedure NSOffsetSpriteLocation( sprite: NSSpritePtr; dh, dv: integer );
- procedure NSSetSpriteBlitter( sprite: NSSpritePtr; blitter: BlitterProc );
- procedure NSSetSpriteSource( sprite: NSSpritePtr; const source_rect, mask_rect: Rect );
- procedure NSSetSpriteRefcon( sprite: NSSpritePtr; refcon: longint );
-
- procedure NSSetPortToBackground( world: NSWorldPtr );
- procedure NSSetPortToWork( world: NSWorldPtr );
- procedure NSSetPortToSprite( world: NSWorldPtr );
- procedure NSSetPortToWindow( world: NSWorldPtr );
-
- procedure NSCopyBitsRect( source_world: GWorldPtr; const source_rect: Rect; dest_world: GWorldPtr; const dest_rect: Rect );
-
- procedure NSCopyBitsNoMaskBlitter( refcon: longint; source: NSFramePtr; const source_rect, mask_rect: Rect; dest: NSFramePtr; const dest_rect: Rect );
- procedure NSBlitter8BitNoMaskDrawProc( refcon: longint; source: NSFramePtr; const source_rect, mask_rect: Rect; dest: NSFramePtr; const dest_rect: Rect );
-
- function InsetSource( const within: Rect; var dest, source, mask: Rect ): boolean;
- function WithinRect( const within, bounds: Rect ): boolean;
-
- implementation
-
- uses
- Memory, OSUtils,
- {$ifc useNSBlitter}
- NSSpriteWorld8BitBlitters,
- {$endc}
- MyMemory, MyAssertions, MyUtils, MyLowLevel, MyMathUtils;
-
- {$setc hack_show_drawing := 0}
-
- var
- null_rect: Rect;
- {$ifc hack_show_drawing}
- hack_world: NSWorldPtr;
- {$endc}
-
- procedure NSCopyBitsRect( source_world: GWorldPtr; const source_rect: Rect; dest_world: GWorldPtr; const dest_rect: Rect );
- begin
- Assert( source_rect.right - source_rect.left = dest_rect.right - dest_rect.left );
- Assert( source_rect.bottom - source_rect.top = dest_rect.bottom - dest_rect.top );
-
- CopyBits( GrafPtr(source_world)^.portBits, GrafPtr(dest_world)^.portBits, source_rect, dest_rect, srcCopy, nil );
- end;
-
- procedure NSCopyBitsNoMaskBlitter( refcon: longint; source: NSFramePtr; const source_rect, mask_rect: Rect; dest: NSFramePtr; const dest_rect: Rect );
- begin
- {$unused( mask_rect, refcon )}
- Assert( source <> nil );
- Assert( dest <> nil );
- NSCopyBitsRect( source^.world, source_rect, dest^.world, dest_rect );
- end;
-
- {$ifc useNSBlitter}
- procedure NSBlitter8BitNoMaskDrawProc( refcon: longint; source: NSFramePtr; const source_rect, mask_rect: Rect; dest: NSFramePtr; const dest_rect: Rect );
- {$ifc not GENERATINGCFM}
- var
- mmuMode: SignedByte;
- {$endc}
- begin
- {$unused( refcon,mask_rect )}
- Assert( (source <> nil) & (dest <> nil) );
- Assert( WithinRect( dest_rect, dest^.bounds ) );
-
- {$ifc not GENERATINGCFM}
- if needSwapMMUMode then begin
- mmuMode := true32b;
- SwapMMUMode( mmuMode );
- end;
- {$endc}
-
- BlitPixie8Bit(
- PixelChunkPtr( AddPtrLong( source^.frameBaseAddr, source^.rowBytes * source_rect.top + source_rect.left ) ),
- PixelChunkPtr( AddPtrLong( dest^.frameBaseAddr, dest^.rowBytes * dest_rect.top + dest_rect.left ) ),
- dest_rect.bottom - dest_rect.top,
- dest_rect.right - dest_rect.left,
- source^.rowBytes,
- dest^.rowBytes );
-
- {$ifc not GENERATINGCFM}
- if needSwapMMUMode then begin
- SwapMMUMode( mmuMode );
- end;
- {$endc}
-
- end;
- {$elsec}
- procedure NSBlitter8BitNoMaskDrawProc( refcon: longint; source: NSFramePtr; const source_rect, mask_rect: Rect; dest: NSFramePtr; const dest_rect: Rect );
- begin
- {$unused( mask_rect, refcon )}
- Assert( source <> nil );
- Assert( dest <> nil );
- NSCopyBitsRect( source^.world, source_rect, dest^.world, dest_rect );
- end;
-
- {$endc}
-
- function InsetSource( const within: Rect; var dest, source, mask: Rect ): boolean;
- begin
- if within.top > dest.top then begin
- source.top := source.top + within.top - dest.top;
- mask.top := mask.top + within.top - dest.top;
- dest.top := within.top;
- end;
- if within.left > dest.left then begin
- source.left := source.left + within.left - dest.left;
- mask.left := mask.left + within.left - dest.left;
- dest.left := within.left;
- end;
- if within.bottom < dest.bottom then begin
- source.bottom := source.bottom + within.bottom - dest.bottom;
- mask.bottom := mask.bottom + within.bottom - dest.bottom;
- dest.bottom := within.bottom;
- end;
- if within.right < dest.right then begin
- source.right := source.right + within.right - dest.right;
- mask.right := mask.right + within.right - dest.right;
- dest.right := within.right;
- end;
- InsetSource := (dest.left < dest.right) & (dest.top < dest.bottom);
- end;
-
- function WithinRect( const within, bounds: Rect ): boolean;
- begin
- WithinRect := (bounds.left <= within.left) & (within.right <= bounds.right) &
- (bounds.top <= within.top) & (within.bottom <= bounds.bottom);
- end;
-
- {$ifc hack_show_drawing}
- procedure HackShowDrawing( dest_frame: NSFramePtr; dest_rect: Rect );
- var
- saved: NSSavedPort;
- begin
- NSSetGWorld( hack_world^.window^.world, saved );
- if dest_frame <> hack_world^.window then begin
- OffsetRect( dest_rect, hack_world^.window^.bounds.left, hack_world^.window^.bounds.top );
- end;
- if odd(Random) then InvertRect( dest_rect );
- NSRestoreGWorld( saved );
- end;
-
- {$endc}
- procedure CallBlitter( blitter: BlitterProc; refcon: longint; source_frame: NSFramePtr; const source_rect, mask_rect: Rect; dest_frame: NSFramePtr; const dest_rect, within_rect: Rect );
- var
- dest, within, source, mask: Rect;
- begin
- if SectRect( dest_frame^.bounds, within_rect, within ) then begin
- dest := dest_rect;
- source := source_rect;
- mask := mask_rect;
- if InsetSource( within, dest, source, mask ) then begin
- blitter( refcon, source_frame, source, mask, dest_frame, dest );
- {$ifc hack_show_drawing}
- HackShowDrawing( dest_frame, dest );
- {$endc}
- end;
- end;
- end;
-
- procedure NSGetGWorld( var saved: NSSavedPort );
- begin
- GetGWorld( saved.world, saved.device );
- end;
-
- procedure NSSetGWorld( world: GWorldPtr; var saved: NSSavedPort );
- begin
- GetGWorld( saved.world, saved.device );
- SetGWorld( world, nil );
- end;
-
- procedure NSRestoreGWorld( const saved: NSSavedPort );
- begin
- SetGWorld( saved.world, saved.device );
- end;
-
- function NSCreateFrame( var frame: NSFramePtr; const bounds: Rect ): OSStatus;
- var
- err: OSStatus;
- pm: PixMapHandle;
- dummy: boolean;
- world: GWorldPtr;
- saved_world: NSSavedPort;
- begin
- Assert( (bounds.left < bounds.right) & (bounds.top < bounds.bottom) );
-
- frame := nil;
-
- err := NewGWorld( world, 8, bounds, nil, nil, 0 );
- if err = noErr then begin
- err := MNewPtr( frame, SizeOf(NSFrame) );
- if err <> noErr then begin
- DisposeGWorld( world );
- end;
- end;
- if err = noErr then begin
- NSSetGWorld( world, saved_world );
-
- pm := GetGWorldPixMap( world );
- Assert( pm <> nil );
- dummy := LockPixels( pm );
- Assert( dummy );
-
- frame^.world := world;
- frame^.pixMap := PixMapPtr(StripAddress(Handle(pm)^));
- frame^.frameBaseAddr := GetPixBaseAddr( pm );
- frame^.rowBytes := pm^^.rowBytes and $7FFF;
- frame^.bounds := bounds;
- frame^.dispose_gworld := true;
-
- EraseRect( bounds );
- FillRect( bounds, qd.ltGray );
-
- NSRestoreGWorld( saved_world );
- end;
- NSCreateFrame := err;
- end;
-
- function NSCreateFrameFromWindow( var frame: NSFramePtr; window: WindowPtr; const bounds: Rect ): OSStatus;
- var
- err: OSStatus;
- pm: PixMapHandle;
- dummy: boolean;
- saved: NSSavedPort;
- window_gworld: GWorldPtr;
- window_device: GDHandle;
- begin
- Assert( (bounds.left < bounds.right) & (bounds.top < bounds.bottom) );
-
- frame := nil;
-
- NSGetGWorld( saved );
-
- SetPort( window );
- GetGWorld( window_gworld, window_device );
-
- err := MNewPtr( frame, SizeOf(NSFrame) );
- if err = noErr then begin
- pm := GetGWorldPixMap( window_gworld );
- Assert( pm <> nil );
- dummy := LockPixels( pm );
- Assert( dummy );
-
- frame^.world := window_gworld;
- frame^.pixMap := PixMapPtr(StripAddress(Handle(pm)^));
- frame^.frameBaseAddr := GetPixBaseAddr( pm );
- frame^.rowBytes := pm^^.rowBytes and $7FFF;
- frame^.bounds := bounds;
- frame^.dispose_gworld := false;
- end;
-
- NSRestoreGWorld( saved );
-
- NSCreateFrameFromWindow := err;
- end;
-
- procedure NSDestroyFrame( var frame: NSFramePtr );
- begin
- if frame <> nil then begin
- Assert( frame^.world <> nil );
- if frame^.dispose_gworld then begin
- DisposeGWorld( frame^.world );
- end;
- MDisposePtr( frame );
- end;
- end;
-
- procedure AddSpriteToGrid( sprite: NSSpritePtr );
- var
- x, y: integer;
- begin
- x := sprite^.dest_rect.left div grid_size;
- if (-1 <= x) & (x < max_grid_size) then begin
- y := sprite^.dest_rect.top div grid_size;
- if (-1 <= y) & (y < max_grid_size) then begin
- sprite^.grid.next := sprite^.world^.grid[ x, y ].next;
- sprite^.grid.prev := @sprite^.world^.grid[ x, y ];
- sprite^.world^.grid[ x, y ].next^.prev := @sprite^.grid;
- sprite^.world^.grid[ x, y ].next := @sprite^.grid;
- end;
- end;
- end;
-
- procedure RemoveSpriteFromGrid( sprite: NSSpritePtr );
- begin
- if sprite^.grid.next <> nil then begin
- sprite^.grid.next^.prev := sprite^.grid.prev;
- sprite^.grid.prev^.next := sprite^.grid.next;
- sprite^.grid.prev := nil;
- sprite^.grid.next := nil;
- end;
- end;
-
- procedure ResetGrid( world: NSWorldPtr );
- var
- x, y: integer;
- sprite: NSSpritePtr;
- begin
- for x := -1 to max_grid_size - 1 do begin
- for y := -1 to max_grid_size - 1 do begin
- world^.grid[ x, y ].next := @world^.grid[ x, y ];
- world^.grid[ x, y ].prev := @world^.grid[ x, y ];
- world^.grid[ x, y ].head := true;
- end;
- end;
- sprite := world^.sprites;
- while sprite <> nil do begin
- sprite^.grid.next := nil;
- sprite^.grid.prev := nil;
- sprite^.grid.head := false;
- if sprite^.visible then begin
- AddSpriteToGrid( sprite );
- end;
- end;
- end;
-
- function NSCreateWorld( var world: NSWorldPtr; window: WindowPtr; const window_bounds, sprite_frame: Rect ): OSStatus;
- var
- err: OSStatus;
- bounds: Rect;
- begin
- Assert( window <> nil );
- Assert( (window_bounds.left < window_bounds.right) & (window_bounds.top < window_bounds.bottom) );
- Assert( (sprite_frame.left = 0) & (sprite_frame.top = 0) );
- Assert( (sprite_frame.left < sprite_frame.right) & (sprite_frame.top < sprite_frame.bottom) );
- Assert( RectWidth( window_bounds ) <= max_sprite_area_size );
- Assert( RectHeight( window_bounds ) <= max_sprite_area_size );
-
- SetRect( null_rect, 0, 0, 0, 0 );
-
- err := MNewPtr( world, SizeOf(NSWorld) );
- if err = noErr then begin
- {$ifc hack_show_drawing}
- hack_world := world;
- {$endc}
- world^.sprites := nil;
- ResetGrid( world );
- world^.change_rect_count := 0;
- world^.offscreen_blitter := NSBlitter8BitNoMaskDrawProc;
-
- SetRect( bounds, 0, 0, window_bounds.right - window_bounds.left, window_bounds.bottom - window_bounds.top );
-
- AddOSStatus( err, NSCreateFrameFromWindow( world^.window, window, window_bounds ) );
- AddOSStatus( err, NSCreateFrame( world^.background, bounds ) );
- AddOSStatus( err, NSCreateFrame( world^.work, bounds ) );
- AddOSStatus( err, NSCreateFrame( world^.sprite, sprite_frame ) );
-
- if err <> noErr then begin
- NSDestroyFrame( world^.window );
- NSDestroyFrame( world^.background );
- NSDestroyFrame( world^.work );
- NSDestroyFrame( world^.sprite );
- end;
- end;
-
- NSCreateWorld := err;
- end;
-
- procedure NSDestroyWorld( var world: NSWorldPtr );
- var
- sprite, tmpsprite: NSSpritePtr;
- begin
- if world <> nil then begin
-
- sprite := world^.sprites;
- while sprite <> nil do begin
- tmpsprite := sprite;
- sprite := sprite^.next;
- NSDestroySprite( tmpsprite );
- end;
-
- NSDestroyFrame( world^.window );
- NSDestroyFrame( world^.background );
- NSDestroyFrame( world^.work );
- NSDestroyFrame( world^.sprite );
- MDisposePtr( world );
- end;
- end;
-
- function NSResize( var world: NSWorldPtr; const newframe: Rect ): OSStatus;
- var
- err: OSStatus;
- bounds: Rect;
- begin
- Assert( world <> nil );
- Assert( RectWidth( world^.window^.bounds ) <= max_sprite_area_size );
- Assert( RectHeight( world^.window^.bounds ) <= max_sprite_area_size );
-
- err := noErr;
-
- if (RectWidth( world^.window^.bounds ) <> RectWidth( newframe )) | (RectHeight( world^.window^.bounds ) <> RectHeight( newframe )) then begin
-
- NSDestroyFrame( world^.background );
- NSDestroyFrame( world^.work );
-
- SetRect( bounds, 0, 0, RectWidth( newframe ), RectHeight( newframe ) );
-
- AddOSStatus( err, NSCreateFrame( world^.background, bounds ) );
- AddOSStatus( err, NSCreateFrame( world^.work, bounds ) );
-
- end;
-
- world^.window^.bounds := newframe;
-
- if err <> noErr then begin
- NSDestroyWorld( world );
- end;
-
- NSResize := err;
- end;
-
- procedure NSAddChangeRect( world: NSWorldPtr; changeRect: Rect );
- label
- again;
- var
- index: integer;
- changedP: RectPtr;
- begin
- Assert( world <> nil );
- if (changeRect.left < changeRect.right) & (changeRect.top < changeRect.bottom) then begin
-
- again:
- if world^.change_rect_count > 0 then begin
- changedP := @world^.change_rects;
- for index := 1 to world^.change_rect_count do begin
- { check for changeRect entirely contained inside changedP }
- if (changedP^.left <= changeRect.left) & (changedP^.top <= changeRect.top) &
- (changedP^.right >= changeRect.right) & (changedP^.bottom >= changeRect.bottom) then begin
- Exit(NSAddChangeRect);
- end;
-
- OffsetPtr( changedP, SizeOf(Rect) );
- end;
-
- changedP := @world^.change_rects;
- for index := 1 to world^.change_rect_count do begin
- { check for changeRect vertically adjacent to changedP }
- if (changedP^.left = changeRect.left) & (changedP^.right = changeRect.right) then begin
- if ((changedP^.top <= changeRect.bottom) & (changeRect.bottom <= changedP^.bottom)) |
- ((changeRect.top <= changedP^.bottom) & (changedP^.bottom <= changeRect.bottom)) then begin
- changedP^.top := Min( changedP^.top, changeRect.top );
- changedP^.bottom := Max( changedP^.bottom, changeRect.bottom );
-
- changeRect := changedP^;
- changedP^ := world^.change_rects[world^.change_rect_count];
- Dec( world^.change_rect_count );
- goto again;
- end;
- end;
-
- { check for changeRect horizontally adjacent to changedP }
- if (changedP^.top = changeRect.top) & (changedP^.bottom = changeRect.bottom) then begin
- if ((changedP^.left <= changeRect.right) & (changeRect.right <= changedP^.right)) |
- ((changeRect.left <= changedP^.right) & (changedP^.right <= changeRect.right)) then begin
- changedP^.left := Min( changedP^.left, changeRect.left );
- changedP^.right := Max( changedP^.right, changeRect.right );
-
- changeRect := changedP^;
- changedP^ := world^.change_rects[world^.change_rect_count];
- Dec( world^.change_rect_count );
- goto again;
- end;
- end;
-
- OffsetPtr( changedP, SizeOf(Rect) );
- end;
-
- changedP := @world^.change_rects;
- index := 1;
- while index <= world^.change_rect_count do begin
- { check for changedP entirely contained by changeRect }
- if (changedP^.left >= changeRect.left) & (changedP^.top >= changeRect.top) &
- (changedP^.right <= changeRect.right) & (changedP^.bottom <= changeRect.bottom) then begin
- changedP^ := world^.change_rects[world^.change_rect_count];
- Dec( world^.change_rect_count );
- end else begin
- Inc(index);
- OffsetPtr( changedP, SizeOf(Rect) );
- end;
- end;
- end;
-
- Assert( world^.change_rect_count < change_rect_max );
- Inc(world^.change_rect_count);
- world^.change_rects[world^.change_rect_count] := changeRect;
- end;
- end;
-
- function IntersectRect( const r1, r2: Rect ): boolean;
- begin
- Assert( (r1.left < r1.right) & (r1.top < r1.bottom) );
- Assert( (r2.left < r2.right) & (r2.top < r2.bottom) );
-
- IntersectRect := not ((r2.right <= r1.left) | (r1.right <= r2.left) | (r2.bottom <= r1.top) | (r1.bottom <= r2.top));
- end;
-
- procedure DoUpdate( world: NSWorldPtr; update: Rect );
- var
- display: Rect;
- blitter: BlitterProc;
- begin
- NSSetPortToWindow( world );
- display := update;
- OffsetRect( display, world^.window^.bounds.left, world^.window^.bounds.top );
- ShieldCursor( display, world^.window^.world^.portPixMap^^.bounds.topleft );
- blitter := NSCopyBitsNoMaskBlitter;
- if world^.window^.pixMap^.pixelSize = 8 then begin
- blitter := NSBlitter8BitNoMaskDrawProc;
- end;
- CallBlitter( blitter, kNoSprite, world^.work, update, null_rect, world^.window, display, world^.window^.bounds );
- ShowCursor;
- end;
-
- procedure NSUpdate( world: NSWorldPtr; update: Rect );
- begin
- OffsetRect( update, -world^.window^.bounds.left, -world^.window^.bounds.top );
- DoUpdate( world, update );
- end;
-
- procedure NSAnimateRect( world: NSWorldPtr; const changed: Rect );
- var
- sprite: NSSpritePtr;
- grid: NSListPtr;
- x, y, x1, y1, x2, y2: integer;
- begin
- NSSetPortToWork( world );
- CallBlitter( world^.offscreen_blitter, kNoSprite, world^.background, changed, null_rect, world^.work, changed, changed );
-
- x1 := Max( -1, changed.left div grid_size - 1 );
- x2 := Min( max_grid_size - 1, changed.right div grid_size );
- y1 := Max( -1, changed.top div grid_size - 1 );
- y2 := Min( max_grid_size - 1, changed.bottom div grid_size );
- for y := y1 to y2 do begin
- for x := x1 to x2 do begin
- grid := world^.grid[ x, y ].next;
- while not grid^.head do begin
- sprite := NSSpritePtr( longint(grid) - sprite_to_grid_offset );
- if IntersectRect( changed, sprite^.dest_rect ) then begin
- CallBlitter( sprite^.blitter, sprite^.refcon, world^.sprite, sprite^.source_rect, sprite^.mask_rect, world^.work, sprite^.dest_rect, changed );
- end;
- grid := grid^.next;
- end;
- end;
- end;
-
- DoUpdate( world, changed );
- end;
-
- procedure NSAnimate( world: NSWorldPtr );
- var
- i: integer;
- begin
- Assert( world <> nil );
-
- for i := 1 to world^.change_rect_count do begin
- NSAnimateRect( world, world^.change_rects[i] );
- end;
- world^.change_rect_count := 0;
-
- end;
-
- procedure NSSetPortToBackground( world: NSWorldPtr );
- begin
- SetGWorld( world^.background^.world, nil );
- end;
-
- procedure NSSetPortToWork( world: NSWorldPtr );
- begin
- SetGWorld( world^.work^.world, nil );
- end;
-
- procedure NSSetPortToSprite( world: NSWorldPtr );
- begin
- SetGWorld( world^.sprite^.world, nil );
- end;
-
- procedure NSSetPortToWindow( world: NSWorldPtr );
- begin
- SetGWorld( world^.window^.world, nil );
- end;
-
- function NSCreateSprite( var sprite: NSSpritePtr; world: NSWorldPtr; const source_rect, mask_rect: Rect ): OSStatus;
- var
- err: OSStatus;
- begin
- Assert( world <> nil );
- Assert( (source_rect.left < source_rect.right) & (source_rect.top < source_rect.bottom) );
- Assert( (world^.sprite^.bounds.left <= source_rect.left) & (source_rect.right <= world^.sprite^.bounds.right) );
- Assert( (world^.sprite^.bounds.top <= source_rect.top) & (source_rect.bottom <= world^.sprite^.bounds.bottom) );
- Assert( (world^.sprite^.bounds.left <= mask_rect.left) & (mask_rect.right <= world^.sprite^.bounds.right) );
- Assert( (world^.sprite^.bounds.top<= mask_rect.top) & (mask_rect.bottom <= world^.sprite^.bounds.bottom) );
- Assert( RectWidth( source_rect ) = RectWidth( mask_rect ) );
- Assert( RectWidth( source_rect ) <= max_sprite_size );
- Assert( RectHeight( source_rect ) = RectHeight( mask_rect ) );
- Assert( RectHeight( source_rect ) <= max_sprite_size );
-
- err := MNewPtr( sprite, SizeOf(NSSprite) );
- if err = noErr then begin
- sprite^.visible := false;
- sprite^.source_rect := source_rect;
- sprite^.mask_rect := mask_rect;
- sprite^.dest_rect := source_rect;
- OffsetRectTo( sprite^.dest_rect, 0, 0 );
- sprite^.blitter := NSCopyBitsNoMaskBlitter;
- sprite^.world := world;
- sprite^.refcon := 0;
- sprite^.grid.next := nil;
- sprite^.grid.prev := nil;
- sprite^.grid.head := false;
-
- sprite^.next := world^.sprites;
- world^.sprites := sprite;
- end;
- NSCreateSprite := err;
- end;
-
- procedure NSDestroySprite( var sprite: NSSpritePtr );
- var
- lastsprite: NSSpritePtr;
- begin
- Assert( sprite <> nil );
- Assert( sprite^.world <> nil );
- Assert( sprite^.world^.sprites <> nil );
-
- RemoveSpriteFromGrid( sprite );
-
- if sprite^.world^.sprites = sprite then begin
- sprite^.world^.sprites := sprite^.next;
- end else begin
- lastsprite := sprite^.world^.sprites;
- while lastsprite^.next <> sprite do begin
- Assert( lastsprite^.next <> nil );
- lastsprite := lastsprite^.next;
- end;
- lastsprite^.next := sprite^.next;
- end;
- MDisposePtr( sprite );
- end;
-
- procedure NSSetSpriteVisible( sprite: NSSpritePtr; visible: boolean );
- begin
- Assert( sprite <> nil );
- Assert( sprite^.world <> nil );
-
- if sprite^.visible <> visible then begin
- if not visible then begin
- RemoveSpriteFromGrid( sprite );
- end;
- NSAddChangeRect( sprite^.world, sprite^.dest_rect );
- sprite^.visible := visible;
- if visible then begin
- AddSpriteToGrid( sprite );
- end;
- end;
- end;
-
- procedure NSSetSpriteLocation( sprite: NSSpritePtr; h, v: integer );
- begin
- Assert( sprite <> nil );
- Assert( sprite^.world <> nil );
-
- if (h <> sprite^.dest_rect.left) | (v <> sprite^.dest_rect.top) then begin
- if sprite^.visible then begin
- RemoveSpriteFromGrid( sprite );
- NSAddChangeRect( sprite^.world, sprite^.dest_rect );
- end;
- OffsetRect( sprite^.dest_rect, -sprite^.dest_rect.left + h, -sprite^.dest_rect.top + v );
- if sprite^.visible then begin
- NSAddChangeRect( sprite^.world, sprite^.dest_rect );
- AddSpriteToGrid( sprite );
- end;
- end;
- end;
-
- procedure NSOffsetSpriteLocation( sprite: NSSpritePtr; dh, dv: integer );
- begin
- Assert( sprite <> nil );
-
- NSSetSpriteLocation( sprite, sprite^.dest_rect.left + dh, sprite^.dest_rect.top + dv );
- end;
-
- procedure NSSetSpriteBlitter( sprite: NSSpritePtr; blitter: BlitterProc );
- begin
- Assert( sprite <> nil );
-
- if blitter <> sprite^.blitter then begin
- if sprite^.visible then begin
- NSAddChangeRect( sprite^.world, sprite^.dest_rect );
- end;
- sprite^.blitter := blitter;
- end;
- end;
-
- procedure NSSetSpriteSource( sprite: NSSpritePtr; const source_rect, mask_rect: Rect );
- begin
- Assert( sprite <> nil );
- Assert( RectWidth( source_rect ) = RectWidth( mask_rect ) );
- Assert( RectWidth( source_rect ) <= max_sprite_size );
- Assert( RectHeight( source_rect ) = RectHeight( mask_rect ) );
- Assert( RectHeight( source_rect ) <= max_sprite_size );
-
- if not EqualRect( source_rect, sprite^.source_rect ) | not EqualRect( mask_rect, sprite^.mask_rect ) then begin
- if sprite^.visible then begin
- NSAddChangeRect( sprite^.world, sprite^.dest_rect );
- end;
- sprite^.source_rect := source_rect;
- sprite^.mask_rect := mask_rect;
- sprite^.dest_rect.right := sprite^.dest_rect.left + RectWidth( source_rect );
- sprite^.dest_rect.bottom := sprite^.dest_rect.top + RectHeight( source_rect );
- if sprite^.visible then begin
- NSAddChangeRect( sprite^.world, sprite^.dest_rect );
- end;
- end;
- end;
-
- procedure NSSetSpriteRefcon( sprite: NSSpritePtr; refcon: longint );
- begin
- Assert( sprite <> nil );
-
- if refcon <> sprite^.refcon then begin
- if sprite^.visible then begin
- NSAddChangeRect( sprite^.world, sprite^.dest_rect );
- end;
- sprite^.refcon := refcon;
- end;
- end;
-
- procedure NSInitSprites;
- begin
- {$ifc not GENERATINGCFM}
- needSwapMMUMode := GetMMUMode <> true32b;
- {$endc}
- end;
-
- end.
-